<template>
  <div class="descriptions">
    <div class="descriptions-wrap">
      <a-row type="flex" :gutter="gutter" class="descriptions-row">
        <template v-for="(item, index) of columns">
          <a-col
            v-if="getVisible(item)"
            :key="item.key || item.field || index"
            :style="item.style"
            :span="item.colSpan || colSpan"
            class="descriptions-col"
          >
            <template v-if="item.customRender">
              <component :is="typeof item.customRender === 'function' ? item.customRender() : item.customRender" />
            </template>
            <slot v-else :name="item.key || item.field" v-bind="getSlotAttrs(item)">
              <description v-bind="getSlotAttrs(item)" :dataSource="dataSource"/>
            </slot>
          </a-col>
        </template>
      </a-row>
    </div>
  </div>
</template>

<script>
import { get, merge } from 'lodash-es';
import Description from './description.vue';

export default {
  name: 'descriptions',
  components: { Description },
  props: {
    /*
     * columns: [
     *   {
     *     key: "", or field: "",
     *     label: "",
     *     colSpan: 12,
     *     labelCol: 6,
     *     wrapperCol: 18,
     *     style: {},
     *     labelStyle: {},
     *     wrapperStyle: {},
     *     format: (v) => v,
     *     visible: Boolean Or () => Boolean
     *   }
     * ] */
    columns: { type: Array, default: () => [] },
    dataSource: { type: Object, default: () => ({}) },
    gutter: { type: Number, default: 12 },
    colSpan: { type: Number, default: 12 },
    labelCol: { type: Number, default: undefined },
    wrapperCol: { type: Number, default: undefined },
    labelStyle: { type: [String, Object], default: undefined },
    wrapperStyle: { type: [String, Object], default: undefined },
    semi: { type: Boolean, default: true },
  },
  methods: {
    getVisible(item) {
      if (typeof item !== 'object' || !item) return false;
      return typeof item.visible === 'function'
        ? item.visible(get(this.dataSource, item.key || item.field), this.dataSource, item)
        : item.visible !== false;
    },
    getSlotAttrs(item) {
      return merge({}, this.$props, item, {
        key: item.key || item.field,
        field: item.key || item.field,
      });
    },
  },
};
</script>

<style>
.descriptions {
  line-height: 1.75;
  .descriptions-wrap {
    overflow: hidden;
    .descriptions-row {
      line-height: inherit;
      color: inherit;
      .descriptions-col {
        white-space: normal;
        word-wrap: break-word;
        word-break: break-all;
        line-height: inherit;
        color: inherit;
      }
    }
  }
}
</style>
